1. Crack hashes with cracking tools
I created sample hashes for cracking. In this document, with various of tools. Be careful of -n
option in echo command, there will be a line feed or carriage return at the end without the option.
$ echo -n "password" | md5sum | awk '{ print $1 }' | tee /tmp/hash.md5
5f4dcc3b5aa765d61d8327deb882cf99
$ echo -n "vuln" | sha1sum | awk '{ print $1 }' | tee /tmp/hash.sha1
f4968830a8fb353e0e8ff1e28750683f189ed6f6
These tools will be used in this document.
-
HashCat
-
John the Ripper
-
RainbowCrack
1.1. Incremental Password Cracking with HashCat
1.1.1. Installation
You can install the hashcat with your favorite package manager.
# apt install hashcat
# dnf install hashcat
$ nix shell nixpkgs#hashcat
But it is so easy to build from source.
git clone https://github.com/hashcat/hashcat
make
Run hashcat
to see it is successfully built.
$ hashcat
Usage: hashcat [options]... hash|hashfile|hccapxfile [dictionary|mask|directory]...
Try --help for more help.
1.1.2. Usage
Pass --hash-type
or -m
to specify the type of target hash. You can browse supported hash algorithms and its examples in example_hashes [hashcat wiki] page. We are going to crack one MD5 hash, and one SHA1 hash in this page. Pass --hash-type 0
to crack a MD5 hash, or --hash-type 100
to crack a SHA1 hash.
hashcat --hash-type 0 # MD5
hashcat --hash-type 3 # SHA1
Select attack mode by passing --attack-mode
or -a
option. Most of the case, you will try brute force attack first. Pass --attack-mode 3
to try brute force attack.
hashcat --attack-mode 3 # Brute Force (Masking)
You might want to crack it with your GPU. Pass --opencl-device-types 2
or -D 2
option.
Most important thing, you need to specify how you would like to let hashcat to build payloads. It is called masking in hashcat
. You can try brute force attack only with 8 digits or 7 alphabet, or with complex combinations.
?l # lowercase: [a-z]
?u # uppercase: [A-Z]
?d # digits: 0123456789
?h # hexadecimal (lowercase): 0123456789abcdef
?H # HexaDecimal (UpperCase): 0123456789ABCDEF
?s # Special characters: «space»!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
?b # Binary: 0x00 - 0xff
?a # Combined: ?l?u?d?s
If you want to crack admin\d{3}
, admin123
for example, you could make a mask admin?d?d?d
.
You can even pass --increment
option to set a range of length of password.
See mask_attack [hashcat wiki] to understand how to build masks, and hashcat [hashcat wiki] to see available options.
1.1.3. Attack!
From above section, I build a command to crack the example hash:
hashcat --attack-mode 3 --hash-type 100 /tmp/hash.sha1 '?l?l?l?l'
-
--attac-mode 3
: Brute force (mask) mode -
--hash-type 100
: SHA1 -
/tmp/hash.sha1
: A hash file. -
?l?l?l?l
: 4 lowercase English alphabets.
It took only 6 seconds to crack the hash.
METAL API (Metal 367.6)
=======================
* Device #1: AMD Radeon Pro 5300M, skipped
* Device #2: Intel(R) UHD Graphics 630, skipped
OpenCL API (OpenCL 1.2 (Dec 13 2024 23:08:33)) - Platform #1 [Apple]
====================================================================
* Device #3: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz, 8160/16384 MB (2048 MB allocatab
* Device #4: Intel(R) UHD Graphics 630, skipped
* Device #5: AMD Radeon Pro 5300M Compute Engine, skipped
Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 256
Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Optimizers applied:
* Zero-Byte
* Early-Skip
* Not-Salted
* Not-Iterated
* Single-Hash
* Single-Salt
* Brute-Force
* Raw-Hash
ATTENTION! Pure (unoptimized) backend kernels selected.
Pure kernels can crack longer passwords, but drastically reduce performance.
If you want to switch to optimized kernels, append -O to your commandline.
See the above message to find out about the exact limits.
Watchdog: Temperature abort trigger set to 100c
Host memory required for this attack: 3 MB
Approaching final keyspace - workload adjusted.
f4968830a8fb353e0e8ff1e28750683f189ed6f6:vuln
Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 100 (SHA1)
Hash.Target......: f4968830a8fb353e0e8ff1e28750683f189ed6f6
Time.Started.....: Mon Mar 3 17:03:46 2025 (0 secs)
Time.Estimated...: Mon Mar 3 17:03:46 2025 (0 secs)
Kernel.Feature...: Pure Kernel
Guess.Mask.......: ?l?l?l?l [4]
Guess.Queue......: 1/1 (100.00%)
Speed.#3.........: 83253.1 kH/s (2.36ms) @ Accel:1024 Loops:26 Thr:1 Vec:4
Recovered........: 1/1 (100.00%) Digests (total), 1/1 (100.00%) Digests (new)
Progress.........: 456976/456976 (100.00%)
Rejected.........: 0/456976 (0.00%)
Restore.Point....: 12288/17576 (69.91%)
Restore.Sub.#3...: Salt:0 Amplifier:0-26 Iteration:0-26
Candidate.Engine.: Device Generator
Candidates.#3....: sdoy -> xqxv
Hardware.Mon.SMC.: Fan0: 84%, Fan1: 83%
Hardware.Mon.#3..: Temp: 57c
Started: Mon Mar 3 17:03:41 2025
Stopped: Mon Mar 3 17:03:47 2025
If a hash is cracked, the status will be 'Cracked'. If every test cases are done but there were no match case, it will be 'Exhausted'. Maybe masks or dictionaries are not enough to crack it.
Session..........: hashcat
Status...........: Exhausted
Hash.Mode........: 0 (MD5)
Hash.Target......: 5f4dcc3b5aa765d61d8327deb882cf99
Time.Started.....: Mon Mar 3 17:38:36 2025 (0 secs)
Time.Estimated...: Mon Mar 3 17:38:36 2025 (0 secs)
Kernel.Feature...: Pure Kernel
Guess.Mask.......: ?d?d?d?d?d?d?d?d [8]
Guess.Queue......: 6/6 (100.00%)
Speed.#3.........: 194.2 MH/s (7.43ms) @ Accel:512 Loops:250 Thr:1 Vec:4
Recovered........: 0/1 (0.00%) Digests (total), 0/1 (0.00%) Digests (new)
Progress.........: 100000000/100000000 (100.00%)
Rejected.........: 0/100000000 (0.00%)
Restore.Point....: 100000/100000 (100.00%)
Restore.Sub.#3...: Salt:0 Amplifier:750-1000 Iteration:0-250
Candidate.Engine.: Device Generator
Candidates.#3....: 13832164 -> 68874949
Hardware.Mon.SMC.: Fan0: 99%, Fan1: 100%
Hardware.Mon.#3..: Temp: 65c
If you do not have any information, so you could not build a mask, you can try cracking without a mask.
hashcat --attack-mode 3 --hash-type 100 /tmp/hash.sha1
If you know constraints about length of password, at least three digits to eight digits at most, you can use --increment
option to do that. You should build the possible mask though.
hashcat --attack-mode 3 --hash-type 100 --increment --increment-min 3 /tmp/hash.sha1 '?d?d?d?d?d?d?d?d'
After cracking, you can find a potfile. Usually located in ~/.local/share/hashcat/hashcat.potfile
.
$ cat ~/.local/share/hashcat/hashcat.potfile
f4968830a8fb353e0e8ff1e28750683f189ed6f6:vuln
See frequently_asked_questions [hashcat wiki] for details about the potfile.
1.2. Dictionary Password Cracking with John the Ripper
John the Ripper, simply john, is a hash and password cracker with a long history. If you have searched about how to crack Windows 7 password etc, you might know about the tool.
1.2.1. How to install John
If you’re using MacOS, or Linuxbrew, you can install John with it.
$ brew install john
If you’re a fan of Nix package manager, you can try john
with it.
$ nix-shell -p john
$ nix run nixpkgs#john # If you're using nix-flake.
1.2.2. How to build John
Building the John is really simple. Let’s start with cloning source code of john
from Github.
$ git clone https://github.com/openwall/john
Cloning into 'john'...
...
$ cd john
You can build John running two commands: configure
and make
.
$ cd src
$ ./configure && make
Ah, you should install libssl
before running ./configure
, or when you see the line
configure: error: libssl not found, install it or use --without-openssl option
1.2.3. Attack!
I passed --wordlist
option with a very famous collection of password, rockyou.txt. And I passed --format
option to make it clear the hash is a raw MD5 hash. At the end, hash.md5
file is the hash file containing the example hash above.
$ john --wordlist=~/Downloads/rockyou.txt --format=RAW-MD5 hash.md5
The cracked password will be shown in less then ten seconds.
Using default input encoding: UTF-8
Loaded 1 password hash (Raw-MD5 [MD5 128/128 SSE4.1 4x5])
Press 'q' or Ctrl-C to abort, 'h' for help, almost any other key for status
password (?)
1g 0:00:00:00 DONE (2025-03-11 21:47) 100.0g/s 32000p/s 32000c/s 32000C/s 123456..101010
Use the "--show --format=Raw-MD5" options to display all of the cracked passwords reliably
Session completed.
2. Cracking a ZIP file with John the Ripper
I prepared an encrypted Zip file.
$ file Downloads/advice.zip
Downloads/advice.zip: Zip archive data, made by v2.0, extract using at least v2.0, last modified, last modified Sun, Apr 27 2025 15:07:02, uncompressed size 54799, method=deflate
You can extract password hash from an encrypted Zip file with zip2john
. It is included in the John the Ripper tool.
$ zip2john ~/Downloads/advice.zip
ver 2.0 advice.zip/advice.jpg PKZIP Encr: TS_chk, cmplen=54721, decmplen=54799, crc=7CA9F10A ts=78E1 cs=78e1 type=8
advice.zip/advice.jpg:$pkzip$1*1*2*0*d5c1*d60f*7ca9f10a*0*28*8*d5c1*78e1*04e6b99ef3a47569769213fead3a7835a68d8c857ed2947ea7e776d187f162324a60975aee8cf1d4e31c99d9c768a8c03c23083c42a6fbdd377abeb53b537642dead500c3a6c766539091736291bbd0d3d6a9f48192faf793f8d8af2e1d3a60bbdb1b53dc7e7a4741cd88faf62c9d823f430510da38a6eea530c2320a9715de6c3ddb7cd43bbfd846f9bb469d5ee7e81080a0ba15aecacf05ba0ef0143984a9bc91379f3b23e508c337dc9c0e5a6f353d4a9a46dfdbae98a1eaffc1814e8db1d2414251f1581e1c147e84333f7c54ed036a3e37c5772170e260369ec1e6936fca5e5a4dd0b3e7f744d2244f14ca54a43ade5c8fe1d0fc02e9b593ff4f6480092efcafaf2f335b7d03c349cae6d152e9a227b...[Truncated]...
Oopsie… We should create a file that contains the hash.
$ zip2john ~/Downloads/advice.zip > /tmp/advice.hash
ver 2.0 advice.zip/advice.jpg PKZIP Encr: TS_chk, cmplen=54721, decmplen=54799, crc=7CA9F10A ts=78E1 cs=78e1 type=8
I would like to use the dictionary rockyou.txt
again. Invoke john
and pass --wordlist=rockyou.txt
option to crack password of the Zip file.
$ john --wordlist=Downloads/rockyou.txt /tmp/advice.hash
Using default input encoding: UTF-8
Loaded 1 password hash (PKZIP [32/64])
Will run 8 OpenMP threads
Press 'q' or Ctrl-C to abort, 'h' for help, almost any other key for status
abcd1234 (advice.zip/advice.jpg)
1g 0:00:00:00 DONE (2025-04-27 17:34) 12.50g/s 204800p/s 204800c/s 204800C/s 123456..christal
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
Yeah, it only takes less than one seconds. And the password was abcd1234
.
3. Cracking and manipulating Flask session
Flask is a famous web framework that you can write a server program in Python. It is simple but have strong features, which can provide routing, session, and so on.
Let’s assume you got a session values from the cookie jar of a web server.
eyJsb2dnZWRfaW4iOmZhbHNlfQ.aBWNJA.MdmDKfF-1oaq1EOx2yid5biXLzg
The first field before the first dot(.) is just a base64 encoded parameter.
$ echo 'eyJsb2dnZWRfaW4iOmZhbHNlfQ==' | base64 -d
{"logged_in":false}
But the others are cryptographic signature, so you cannot modify the signature; it will fail at the sanity check process.
3.1. Installing python
The Flask Unsign tool can help you crack the session. It is a command line tool to fetch, decode, crack, and manipulate session cookie that is used in Flask framework.
You can install it simply invoking pip
in your system.
pip install flask-unsign[wordlist]
Test it by passing --decode
command. It would show the same result from the previous section.
$ flask-unsign --cookie 'eyJsb2dnZWRfaW4iOmZhbHNlfQ.aBWNJA.MdmDKfF-1oaq1EOx2yid5biXLzg' --decode
{'logged_in': False}
It will also install the Flask Unsign Wordlist. So you can use the brute force feature that the Flask Unsign tool provides.
You can pass --unsign
option to crack the cookie.
flask-unsign.exe --unsign --cookie 'eyJsb2dnZWRfaW4iOmZhbHNlfQ.aBWNJA.MdmDKfF-1oaq1EOx2yid5biXLzg'
[*] Session decodes to: {'logged_in': False}
[*] No wordlist selected, falling back to default wordlist..
[*] Starting brute-forcer with 8 threads..
[*] Attempted (2176): -----BEGIN PRIVATE KEY-----ECR
[+] Found secret key after 19584 attempts##NjPFXYQ809
'password'
Yeah, the password was 'password'. Now you can craft(modify) the session variable with the obtained password.
$ flask-unsign --secret 'password' --sign --cookie "{'logged_in': True}"
eyJsb2dnZWRfaW4iOnRydWV9.aBWWkg.VinuJtDFAVq5Q0-e9wfcCd5R8TI
It would work.